package com.jochen.core.android

import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Intent
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.text.Html
import android.view.Gravity
import android.widget.HorizontalScrollView
import android.widget.RelativeLayout
import android.widget.ScrollView
import android.widget.TextView
import java.io.PrintWriter
import java.io.StringWriter

object UncaughtExceptionHandler {  
    var targetActivityClass: Class<out Activity>? = null

    const val LAUNCH_MODE = "launchMode"
    const val LAUNCH_MODE_NORMAL = 0
    const val LAUNCH_MODE_CRASH = 1

    fun init(activity: Activity, targetClass: Class<out Activity>) {
        targetActivityClass = targetClass
        Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
            activity.runOnUiThread {
                handleCrash(activity, thread, throwable)
            }
        }
    }

    private fun handleCrash(activity: Activity, thread: Thread, throwable: Throwable) {
        val stackTrace = StringWriter().apply {
            throwable.printStackTrace(PrintWriter(this))
        }.toString()

        Intent(activity, UncaughtExceptionActivity::class.java).apply {
            addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
            putExtra(LAUNCH_MODE, LAUNCH_MODE_CRASH)
            putExtra("title", "全局未捕获异常: ${throwable.message}")
            putExtra("msg", "Thread: $thread\nStackTrace: $stackTrace")
            activity.startActivity(this)
        }
        android.os.Process.killProcess(android.os.Process.myPid())
    }

    fun formatColoredText(text: String, colorHex: String): String {
        return "<font color='$colorHex'>${text.replace("\n", "<br>")}</font>"
    }
}

class UncaughtExceptionActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        setContentView(RelativeLayout(this).apply {
            setBackgroundColor(Color.BLACK)
            gravity = Gravity.CENTER
        })

        if (intent.getIntExtra(UncaughtExceptionHandler.LAUNCH_MODE, 
                              UncaughtExceptionHandler.LAUNCH_MODE_NORMAL) == 
            UncaughtExceptionHandler.LAUNCH_MODE_CRASH) {
            
            showCrashDialog(
                intent.getStringExtra("title") ?: "",
                intent.getStringExtra("msg") ?: ""
            )
        }
    }

    private fun showCrashDialog(title: String, message: String) {
        Dialog(this).apply {
            setTitle(title)
            setContentView(R.layout.dialog_exception_layout)
            
            findViewById<TextView>(R.id.dialog_exception_errMsg).text = 
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    Html.fromHtml(
                        UncaughtExceptionHandler.formatColoredText(message, "#FF0000"),
                        Html.FROM_HTML_MODE_COMPACT
                    )
                } else {
                    message
                }
            
            setOnDismissListener { launchTargetActivity() }
            show()
        }
    }

    private fun launchTargetActivity() {
        UncaughtExceptionHandler.targetActivityClass?.let { targetClass ->
            Intent(this, targetClass).apply {
                flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
                startActivity(this)
            }
            finish()
            android.os.Process.killProcess(android.os.Process.myPid())
        }
    }
}